<script setup lang="ts">
import { getMemberAddressById, postMemberAddress, putMemberAddress } from '@/services/address'
import type { PostMemberAddressData } from '@/types/address'
import { validate, type Rules } from '@/utils/validate'
import { onLoad } from '@dcloudio/uni-app'
import { reactive, ref } from 'vue'

const { id } = defineProps<{
  id: string
}>()
onLoad(() => {
  uni.setNavigationBarTitle({
    title: id ? '修改地址' : '新建地址',
  })
})

// 如果是确定字段的表单，可以通过 reactive 定义响应式数据
const form = reactive({
  isDefault: 0, // 修复默认收货地址报错
} as PostMemberAddressData)

// 自定义校验规则
const rules: Rules = {
  receiver: [{ required: true, message: '请填写收货人姓名' }],
  contact: [
    { required: true, message: '请填写收货人手机号码' },
    { pattern: /^1\d{10}$/, message: '请填写正确的手机号码' },
  ],
  provinceCode: [{ required: true, message: '请选择收货人所在城市' }],
  address: [{ required: true, message: '请填写详细收货地址' }],
}

// 点击提交表单按钮
const submitFrom = async () => {
  // 如果表单校验失败，退出函数
  if (!validate(form, rules)) return
  // console.log('当前收集到的表单数据有', form)
  if (addressId.value) {
    // 如果有 id 调用：修改地址请求
    await putMemberAddress(addressId.value, form)
    uni.showToast({ title: '修改成功~' })
  } else {
    // 没有 id 调用：添加地址请求
    await postMemberAddress(form)
    uni.showToast({ title: '添加成功~' })
  }
  setTimeout(() => {
    // 后退到上一页
    uni.navigateBack({})
  }, 300)
}

// 用于用户界面展示的省市区
const fullLocation = ref<string | undefined>()
// 省/市/县 Picker
const regionChange = (ev: any) => {
  // 收集省市区编码
  const [provinceCode, cityCode, countyCode] = (ev as WechatMiniprogram.PickerChange).detail.code
  // 收集用于后端所需的参数
  // 👍 ES6新增API：Object.assign 合并对象，把省市区编码合并到 form 中
  Object.assign(form, {
    provinceCode,
    cityCode,
    countyCode,
    postalCode: ev.detail.postcode, // 邮政编码
  })
  // 修改用户界面展示的省市区
  fullLocation.value = (ev.detail.value as string[]).join('')
}

// 是否默认收获地址
// 🚨 踩坑：小程序有 switch 组件，原生 SVG 有 switch 标签，二者都有 change 事件，两个事件对象类型出现冲突
// 🔔 解决方案：事件对象用联合类型兼容二者，内部再通过 as 断言指定具体类型
const isDefaultChange = (ev: any) => {
  // 是否为默认，1为是，0为否
  form.isDefault = (ev as WechatMiniprogram.SwitchChange).detail.value ? 1 : 0
}

// 页面加载时获取 id
const addressId = ref('')
onLoad(async () => {
  // 如果有地址 id
  if (id) {
    // 保存地址 id
    addressId.value = id
    // 根据 id 获取地址详情
    const res = await getMemberAddressById(id)
    // 地址合并到表单中，用于点保存时，提交给后端用的
    Object.assign(form, res)
    // 更新用于界面展示的 省 市 区 (无需添加到表单字段中，仅用于用户界面展示)
    fullLocation.value = res.fullLocation
  }
})
</script>

<template>
  <view class="viewport">
    <!-- 地址信息 -->
    <view class="form">
      <view class="form-item">
        <text class="label">姓名</text>
        <input
          v-model="form.receiver"
          placeholder-style="color: #888"
          placeholder="请填写收货人姓名"
        />
      </view>
      <view class="form-item">
        <text class="label">手机号码</text>
        <input
          v-model="form.contact"
          placeholder-style="color: #888"
          placeholder="请填写收货人手机号码"
        />
      </view>
      <view class="form-item">
        <text class="label">省/市/县 (区)</text>
        <picker @change="regionChange" mode="region">
          <view v-if="fullLocation" class="region"> {{ fullLocation }} </view>
          <view v-else class="placeholder"> 请填写收货人所在城市 </view>
        </picker>
      </view>
      <view class="form-item">
        <text class="label">详细地址</text>
        <input
          v-model="form.address"
          placeholder-style="color: #888"
          placeholder="街道、楼牌号信息"
        />
      </view>
      <view class="form-item">
        <text class="label">设置默认地址</text>
        <switch @change="isDefaultChange" :checked="form.isDefault === 1" color="#27ba9b" />
      </view>
    </view>
    <!-- 提交按钮 -->
    <view class="button" @tap="submitFrom">
      {{ addressId ? '保 存' : '确 认' }}
    </view>
  </view>
</template>

<style>
page {
  background-color: #f4f4f4;
}

.form {
  margin: 20rpx 20rpx 0;
  padding: 0 20rpx;
  border-radius: 10rpx;
  background-color: #fff;
}

.form .form-item {
  display: flex;
  min-height: 96rpx;
  line-height: 46rpx;
  padding: 25rpx 10rpx;
  background-color: #fff;
  font-size: 28rpx;
  border-bottom: 1rpx solid #ddd;
  position: relative;
}

.form .form-item:last-child {
  border: none;
}

.form .form-item .label {
  width: 200rpx;
  color: #333;
}

.form .form-item input {
  flex: 1;
  display: block;
  height: 46rpx;
}

.form .form-item switch {
  position: absolute;
  right: -10rpx;
  transform: scale(0.7) translateY(-8px);
}

.form .form-item picker {
  flex: 1;
}

.form .form-item .region {
  color: #333;
}

.form .form-item .placeholder {
  color: #888;
}

.button {
  height: 80rpx;
  text-align: center;
  line-height: 80rpx;
  margin: 30rpx 20rpx;
  color: #fff;
  border-radius: 80rpx;
  font-size: 30rpx;
  background-color: #27ba9b;
}
</style>
